package com.github.llyb120.driver.qiuya;


import com.github.llyb120.driver.qiuya.request.ReqBase;
import com.github.llyb120.json.Arr;
import com.github.llyb120.json.Obj;

import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

import static com.github.llyb120.driver.qiuya.request.ReqBase.COMMAND_SHOW_DBS;
import static com.github.llyb120.json.Json.a;
import static com.github.llyb120.json.Json.o;

public class QiuyaClient {
    private String host = "127.0.0.1";
    private String port = "28018";
    public WebSocket ws;
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.WriteLock wl;
    private ReentrantReadWriteLock.ReadLock rl;
    private Map<String, Database> dbMap = new HashMap<>();

    QiuyaClient(String host, String port){
        this.host = host;
        this.port = port;
        this.wl = lock.writeLock();
        this.rl = lock.readLock();
        this.init();
    }

    private void init(){
        this.ws = new WebSocket(String.format("http://%s:%s/websocket/", host, port));
    }

    public Database getDatabase(String dbname){
        wl.lock();
        Database item = dbMap.get(dbname);
        if (item == null) {
            item = new Database(this, dbname);
            dbMap.put(dbname, item);
        }
        wl.unlock();
        return item;
    }


    public List<String> show(){
            Obj obj = send(COMMAND_SHOW_DBS, new ReqBase(null, null));
                return obj.aa("data")
                        .stream()
                        .map(e -> (String)(e))
                        .collect(Collectors.toList());
    }


    Obj send(String event, Object args){
        try {
            Obj obj = this.ws.send(event, args).get();
            if (obj == null) {
                obj = o();
            }
            if(!obj.ss("code").equals("0")){
                throw new RuntimeException();
            }
            return obj;
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }


}
